package com.ap.core.jbehave.managemerchant;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;

import java.io.IOException;

import org.apache.commons.io.IOUtils;
import org.hamcrest.CoreMatchers;
import org.jbehave.core.annotations.Given;
import org.jbehave.core.annotations.Then;
import org.jbehave.core.annotations.When;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

import com.ap.core.cxf.jaxb.common.APCORE1FaultDetailsType;
import com.ap.core.cxf.jaxb.common.RequestTypeCode;
import com.ap.core.cxf.jaxb.managemerchant.RequestMerchantRegistrationType;
import com.ap.core.cxf.jaxb.managemerchant.ResponseMerchantRegistrationType;
import com.ap.core.cxf.jaxb.managepayment.RetrieveRTP1Response;
import com.ap.core.jbehave.BaseTransitionRTPSteps;
import com.ap.core.jbehave.StoryContext;
import com.ap.core.util.JaxbUtil;
import com.ap.core.util.TypedKey;
import com.ap.generator.registermerchant.RequestManageMerchantGeneratorBuilder;
import com.core.ap.wsdl.managemerchantservice_1.ManageMerchant1PortType;
import com.core.ap.wsdl.managemerchantservice_1.RegisterMerchant1Fault;

public class ManageMerchantFaultSteps extends BaseTransitionRTPSteps {

    private RequestMerchantRegistrationType requestMerchantRegistrationType;
    private ResponseMerchantRegistrationType responseMerchantRegistrationType;
    /**
     * @param storyContext
     */
    public ManageMerchantFaultSteps(StoryContext storyContext) {
        super(storyContext);
    }

    @Given("that the Distributor has been on-boarded and is registered for AP Service")
    public void givenDistributorOnBoarded() {
    }

    @Given("a merchant requests their Distributor for ZAPP enrolment")
    public void givenMerchantRequestedForZappEnrolment() {
    }

    @Given("with RequestType as REGISTER")
    public void givenWithRequestTypeAsREGISTER() throws IOException {
        requestMerchantRegistrationType = RequestManageMerchantGeneratorBuilder.getRequestManageMerchantGeneratorBuilder().build().generate();
        requestMerchantRegistrationType.getMerchant().setRequestType(RequestTypeCode.REGISTER);
        final Resource resource = new ClassPathResource("data/image.jpg");
        byte[] bytes = IOUtils.toByteArray(resource.getInputStream());
        requestMerchantRegistrationType.getMerchant().setMerchantLogo(bytes);
        JaxbUtil.newInstance().javaToXML(RequestMerchantRegistrationType.class, requestMerchantRegistrationType);
    }

    @When("Distributor submits erroneous requests (valid and correct form) to AP Service to add merchant to their ZAPP Profile/account")
    public void whenDistributorRequestsToAPServiceToAddMerchantToTheirZAPPProfileAccount() throws Exception {
    	requestMerchantRegistrationType.setDistributorId("000001");
        requestMerchantRegistrationType.getMerchant().setMerchantId("000001");
        final ManageMerchant1PortType manageMerchant1PortType = factory.getBean(ManageMerchant1PortType.class);
        checkFault(new TypedKey<RegisterMerchant1Fault>("RV0023"),manageMerchant1PortType, requestMerchantRegistrationType);
    }

    @Then("AP Service should send the appropriate fault information back to OSB")
    public void thenAPServiceSendsResponseToDistributorWithUpdateStatusAsSuccessful() {
    	LOG.info("Then - AP Service should send the appropriate fault information back to OSB");
    	for (TypedKey<RegisterMerchant1Fault> key : storyContext.keySet()) {
			APCORE1FaultDetailsType fault = storyContext.get(key).getFaultInfo();
			StringBuilder stringBuilder = new StringBuilder(150);
	    	stringBuilder.append("\n FaultString:"+fault.toString());
	    	stringBuilder.append(" FaultId:"+fault.getFaultid());
	    	stringBuilder.append("\n"+" Errorcode:"+fault.getErrorcode());
	        stringBuilder.append( " ErrorMessage:"+fault.getErrormessage());
	        stringBuilder.append("\n"+" InternalErrorCode:"+fault.getInternalcode());
	        stringBuilder.append(" InternalErrorMessage:"+fault.getInternalmessage());
	        String message = stringBuilder.toString();
			LOG.info("\n\nFault Error Details for "	+key+ " :"+ message+"\n");
			JaxbUtil.newInstance().javaToXML(APCORE1FaultDetailsType.class, fault);

			assertThat("Fault Id is not as expected", false, CoreMatchers.is(equalTo(fault.getFaultid() == null)));
		    assertThat("Error code is not as expected",	false,	CoreMatchers.is(equalTo(fault.getErrorcode() == null)));
		    assertThat("Error Message is not as expected", false, CoreMatchers.is(equalTo(fault.getErrormessage() == null)));
		    assertThat("Internal Code is not as expected", false, CoreMatchers.is(equalTo(fault.getInternalcode() == null)));
		    assertThat("Internal Message is not as expected", false, CoreMatchers.is(equalTo(fault.getInternalmessage() == null)));
		}
		
    }
    
    private void checkFault(TypedKey<RegisterMerchant1Fault> FAULT,	final ManageMerchant1PortType manageMerchant1PortType,
    		RequestMerchantRegistrationType requestMerchantRegistrationType) {
		try {
			
			responseMerchantRegistrationType = manageMerchant1PortType.registerMerchant1(requestMerchantRegistrationType);
			LOG.info("When -  Response Received");
			JaxbUtil.newInstance().javaToXML(RetrieveRTP1Response.class, responseMerchantRegistrationType);
			
		} catch (RegisterMerchant1Fault fault) {
			storyContext.put(FAULT, fault);
		}
	}

}
